//		ID : Xerxes
//      "I have not failed, I have just found 10000 ways that won't work.
//


#include <iostream>
#include <algorithm>
#include <vector>
#include <sstream>
#include <fstream>
#include <string>
#include <list>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <functional>
#include <bitset>

#include <ctime>
#include <cassert>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <climits>
#include <cstring>
#include <cstdlib>

using namespace std;

#define VI vector< int >
#define CI( x ) scanf("%d",&x)
#define CL( x ) scanf("%lld",&x)
#define CD( x ) scanf("%lf",&x )
#define fo(i,st,ed) for(int i = st ; i < ed ; ++i )
#define foE(i,st,ed) for(int i = st ; i <= ed ; ++i )
#define foit(i, x) for (typeof((x).begin()) i = (x).begin(); i != (x).end(); i++)
#define bip system("pause")
#define Int long long
#define pb push_back
#define SZ(X) (int)(X).size()
#define LN(X) (int)(X).length()
#define mk make_pair
#define f first
#define s second
#define SET( ARRAY , VALUE ) memset( ARRAY , VALUE , sizeof(ARRAY) )
#define tp pair< int, pair<int,int> >
#define mmk( x, y , z ) mk( x, mk( y, z ) )



inline void wait( double seconds ){
    double endtime = clock()+( seconds* CLOCKS_PER_SEC );
    while( clock() < endtime ){
        ;
    }
}
const int inf = (int)1e6+100;
int root[inf+10];
int rank[inf+10];

inline void _Set() {
    fo(i,0,inf) {
        root[i]=i;
        rank[i]=0;
    }
}
inline int _Find(int x) {
    if( x!= root[x] ) {
        root[x] = _Find( root[x] );
    }
    return root[x];
}
inline void _Union(int x, int y) {
    int px = _Find(x);
    int py = _Find(y);
    if( rank[px] > rank[py] ) {
        root[py] = px;
    } else {
        root[px] = py;
    }
    if( rank[px] == rank[py]) {
        rank[py]+=1;
    }
}

int n; // number of nodes;
struct NODE{
	int x,y;
	double c;
	NODE(int x_, int y_, double c_):
	x(x_),y(y_),c(c_){;}
};
vector< NODE > points;

inline void Read(){
		_Set();
		int x,y;		
		vector< pair<int,int> > vt;
		fo(i,0,n){
			scanf("%d %d",&x,&y) ;
			vt.pb( mk(x,y) );
		}
		
		points.clear();
		fo(i,0,n){
			fo(j,i+1,n){
				double d = sqrt( (double) ( (vt[i].f-vt[j].f)*(vt[i].f-vt[j].f) + (vt[i].s-vt[j].s)*(vt[i].s-vt[j].s) ) );
				points.pb( NODE(i,j,d) );
			}
		}
		
		int already_connected;
		int point1,point2;
		CI(already_connected);
		fo(i,0,already_connected){
			CI(point1);
			CI(point2);
			point1--;
			point2--;
			_Union(point1,point2);			
		}
		
}
inline bool cmp(NODE A, NODE B){
	return ( A.c < B.c ) ;
}
inline void Proc(){
		double cost=0;
		sort(points.begin(),points.end(), cmp);
		for(int i=0, j = SZ(points) ; i < j ; ++i ){
			int x = points[i].x;
			int y = points[i].y;
			double c = points[i].c;
			if( _Find(x)!=_Find(y) ){
				_Union(x,y);
				cost+=c;
			}
		}
		
		printf("%.2lf\n",cost);
}
int main(){
    #ifndef ONLINE_JUDGE
        freopen("in","rt",stdin);
    #endif
	
	while( scanf("%d",&n)==1 ) {
		Read();
		Proc();
	}

return 0;
}


